﻿using LessonStudio.Models;
using MahApps.Metro.Controls;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WindowsInput;
using WindowsInput.Native;

namespace LessonStudio
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : MetroWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            InitUI();
            BindEvents();
        }

        private void OnMainWindowLoaded(object sender, RoutedEventArgs e)
        {
            //全屏
            this.WindowState = WindowState.Normal;
            this.WindowStyle = WindowStyle.None;
            this.ResizeMode = ResizeMode.NoResize;
            this.IgnoreTaskbarOnMaximize = true;
            this.Topmost = true;
            this.Left = 0;
            this.Top = 0;
            this.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
            this.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
        }

        private void OnWindowKeyDown(object sender, KeyEventArgs e)
        {
            //
            if (e.Key == Key.Right)
            {
                //翻页
                NextPage();
            }
            else if (e.Key == Key.Left)
            {
                //翻页
                PrevPage();
            }
            else if (e.KeyboardDevice.Modifiers == ModifierKeys.Alt && e.Key == Key.F4)
            {
                //退出程序
                Close();
            }
            else if (e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.O)
            {
                //Ctrl+O
                //打开文件;
                OpenFile();
            }
            else if (e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.E)
            {
                //Ctrl+E
                //显示画板
                //if(canvasInk.Visibility == Visibility.Visible)
                //{
                //    canvasInk.Visibility = Visibility.Collapsed;
                //}
                //else
                //{
                //    canvasInk.Visibility = Visibility.Visible;
                //}
                //删除状态
                canvasInk.EditingMode = InkCanvasEditingMode.EraseByStroke;
            }
            else if (e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.H)
            {
                //隐藏上面的各个按钮
                if (gridButtons.Visibility == Visibility.Collapsed)
                {
                    gridButtons.Visibility = Visibility.Visible;
                    ShowCloseButton = true;
                }
                else
                {
                    gridButtons.Visibility = Visibility.Collapsed;
                    ShowCloseButton = false;
                }
            }
            else if (e.Key == Key.Escape)
            {
                //退出全屏
            }
        }

        private void OnButtonNewLessonClick(object sender, RoutedEventArgs e)
        {
            //新建课件
            var lesson = new Models.LessonDescription();
            var wnd = new UI.LessonEditWnd(_appSetting, lesson);
            wnd.OnOK += () => {
                _lessons.Add(lesson);
                gridSub.Children.Clear();
                gridSub.Visibility = Visibility.Collapsed;
                panelMain.Visibility = Visibility.Visible;
            };
            wnd.OnCancel += () => {
                gridSub.Children.Clear();
                gridSub.Visibility = Visibility.Collapsed;
                panelMain.Visibility = Visibility.Visible;
            };
            gridSub.Children.Clear();
            gridSub.Children.Add(wnd);
            panelMain.Visibility = Visibility.Collapsed;
            gridSub.Visibility = Visibility.Visible;
        }

        private void OnButtonUpdateBaseDirClick(object sender, RoutedEventArgs e)
        {
            try {
                var dialog = new System.Windows.Forms.FolderBrowserDialog();
                dialog.SelectedPath = _appSetting.LessonBaseDir;
                var ret = dialog.ShowDialog();
                if (ret == System.Windows.Forms.DialogResult.OK)
                {
                    _appSetting.LessonBaseDir = dialog.SelectedPath;
                    textBaseDir.Text = _appSetting.LessonBaseDir;
                    LoadLessons(_appSetting.LessonBaseDir);
                    SaveLessonBaseDir();
                }
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.Message);
            }
        }

        private void OnButtonLessonViewClick(object sender, RoutedEventArgs e)
        {
            //查看课件
            var btn = sender as Button;
            if (btn == null)
                return;

            var lesson = btn.DataContext as Models.LessonDescription;
            if (lesson == null)
                return;

            var wnd = new UI.LessonViewWnd(_appSetting, lesson);
            wnd.OnCancel += () => {
                this.ShowTitleBar = true;
                this.ShowMinButton = true;
                this.ShowCloseButton = true;
                gridSub.Children.Clear();
                gridSub.Visibility = Visibility.Collapsed;
                panelMain.Visibility = Visibility.Visible;
            };
            gridSub.Children.Clear();
            gridSub.Children.Add(wnd);
            panelMain.Visibility = Visibility.Collapsed;
            gridSub.Visibility = Visibility.Visible;
            this.ShowTitleBar = false;
            this.ShowMinButton = false;
            this.ShowCloseButton = false;
        }

        private bool _isLoaded = false;
        private void FileButton_Click(object sender, RoutedEventArgs e)
        {
            OpenFile();
        }

        private void ZoomInButton_Click(object sender, RoutedEventArgs e)
        {
            if (_isLoaded)
            {
                moonPdfPanel.ZoomIn();
            }
        }

        private void ZoomOutButton_Click(object sender, RoutedEventArgs e)
        {
            if (_isLoaded)
            {
                moonPdfPanel.ZoomOut();
            }
        }

        private void NormalButton_Click(object sender, RoutedEventArgs e)
        {
            if (_isLoaded)
            {
                moonPdfPanel.Zoom(1.0);
            }
        }

        private void FitToHeightButton_Click(object sender, RoutedEventArgs e)
        {
            moonPdfPanel.ZoomToHeight();
        }

        private void FacingButton_Click(object sender, RoutedEventArgs e)
        {
            moonPdfPanel.ViewType = MoonPdfLib.ViewType.Facing;
        }

        private void SinglePageButton_Click(object sender, RoutedEventArgs e)
        {
            moonPdfPanel.ViewType = MoonPdfLib.ViewType.SinglePage;
        }

        private void OnButtonPdfToImageClick(object sender, RoutedEventArgs e)
        {
            var wnd = new UI.PdfConvertorWnd();
            wnd.OnCancel += () => {
                //this.ShowTitleBar = true;
                //this.ShowMinButton = true;
                //this.ShowCloseButton = true;
                gridSub.Children.Clear();
                gridSub.Visibility = Visibility.Collapsed;
                panelMain.Visibility = Visibility.Visible;
            };
            gridSub.Children.Clear();
            gridSub.Children.Add(wnd);
            panelMain.Visibility = Visibility.Collapsed;
            gridSub.Visibility = Visibility.Visible;
            //this.ShowTitleBar = false;
            //this.ShowMinButton = false;
            //this.ShowCloseButton = false;
        }

        #region 辅助函数
        List<StrokeCollection> _strokes = null;
        int _currentPage = -1;
        void InitUI()
        {
            listboxLessons.ItemsSource = _lessons;
            GetAppSettingFilePath();
            LoadLessonBaseDir();
            LoadLessons(_appSetting.LessonBaseDir);
            textBaseDir.Text = _appSetting.LessonBaseDir;
            //canvasInk.DefaultDrawingAttributes.Color = Colors.Red;
            //canvasInk.DefaultDrawingAttributes.Width = 4;
            //canvasInk.DefaultDrawingAttributes.Height = 4;
            //canvasInk.DefaultDrawingAttributes.IsHighlighter = true;
            //canvasInk.EditingMode = InkCanvasEditingMode.
        }

        void BindEvents()
        {
            this.Loaded += OnMainWindowLoaded;
            this.KeyDown += OnWindowKeyDown;
            btnNewLesson.Click += OnButtonNewLessonClick;
            btnUpdateBaseDir.Click += OnButtonUpdateBaseDirClick;
            btnPdfToImage.Click += OnButtonPdfToImageClick;
        }

        void OpenFile()
        {
            var dialog = new OpenFileDialog();

            if (dialog.ShowDialog().GetValueOrDefault())
            {
                string filePath = dialog.FileName;

                try
                {
                    moonPdfPanel.OpenFile(filePath);
                    moonPdfPanel.ZoomToHeight();
                    canvasInk.Strokes.Clear();
                    _currentPage = 0;
                    var pages = moonPdfPanel.TotalPages;
                    _strokes = new List<StrokeCollection>(pages);
                    for (int i = 0; i < pages; i++)
                    {
                        _strokes.Add(new StrokeCollection());
                    }

                    _isLoaded = true;
                    gridTip.Visibility = Visibility.Collapsed;
                }
                catch (Exception exp)
                {
                    System.Diagnostics.Debug.WriteLine(exp);
                    _isLoaded = false;
                }
            }

        }

        void UpdatePenColor(Color color)
        {
            canvasInk.DefaultDrawingAttributes.Color = color;
        }

        void UpdatePenThickness(double w, double h)
        {
            canvasInk.DefaultDrawingAttributes.Width = w;
            canvasInk.DefaultDrawingAttributes.Height = h;
        }

        void UpdatePenHighlighter(bool bHighlighter)
        {
            canvasInk.DefaultDrawingAttributes.IsHighlighter = bHighlighter;
        }

        void UpdateEditMode(InkCanvasEditingMode mode)
        {
            canvasInk.EditingMode = mode;
        }

        /// <summary>
        /// 备份画笔
        /// </summary>
        void SaveStrokes()
        {
            var page = moonPdfPanel.GetCurrentPageNumber();
            System.Diagnostics.Debug.WriteLine(string.Format("PAGE:{0} VS CUR:{1}", page, _currentPage));
            _strokes[_currentPage].Clear();
            _strokes[_currentPage].Add(canvasInk.Strokes);
        }
        void LoadStrokes()
        {
            var page = moonPdfPanel.GetCurrentPageNumber();
            System.Diagnostics.Debug.WriteLine(string.Format("PAGE:{0} VS CUR:{1}", page, _currentPage));
            canvasInk.Strokes.Clear();
            canvasInk.Strokes.Add(_strokes[_currentPage]);
        }

        private void NextPage()
        {
            SaveStrokes();
            if (_currentPage < _strokes.Count - 1)
            {
                _currentPage++;
                moonPdfPanel.GotoPage(_currentPage + 1);
                //moonPdfPanel.GotoNextPage();
                LoadStrokes();
            }
        }

        private void PrevPage()
        {
            SaveStrokes();
            if (_currentPage > 0)
            {
                _currentPage--;
                //moonPdfPanel.GotoPreviousPage();
                moonPdfPanel.GotoPage(_currentPage + 1);
                LoadStrokes();
            }
        }

        #endregion

        #region Commands
        #endregion

        private void OnButtonColorBlackClick(object sender, RoutedEventArgs e)
        {
            UpdatePenColor(Colors.Black);
        }

        private void OnButtonColorRedClick(object sender, RoutedEventArgs e)
        {
            UpdatePenColor(Colors.Red);
        }

        private void OnButtonColorBlueClick(object sender, RoutedEventArgs e)
        {
            UpdatePenColor(Colors.Blue);
        }

        private void OnButtonColorGreenClick(object sender, RoutedEventArgs e)
        {
            UpdatePenColor(Colors.Green);
        }

        private void OnButtonThickness4Click(object sender, RoutedEventArgs e)
        {
            UpdatePenThickness(4, 4);
        }

        private void OnButtonThickness6Click(object sender, RoutedEventArgs e)
        {
            UpdatePenThickness(6, 6);
        }

        private void OnButtonThickness8Click(object sender, RoutedEventArgs e)
        {
            UpdatePenThickness(8, 8);
        }

        private void OnButtonThickness10Click(object sender, RoutedEventArgs e)
        {
            UpdatePenThickness(10, 10);
        }

        private void OnButtonThickness12Click(object sender, RoutedEventArgs e)
        {
            UpdatePenThickness(12, 12);
        }

        private void OnButtonThickness16Click(object sender, RoutedEventArgs e)
        {
            UpdatePenThickness(16, 16);
        }

        private void OnButtonHighlighterFalseClick(object sender, RoutedEventArgs e)
        {
            UpdatePenHighlighter(false);
        }

        private void OnButtonHighlighterTrueClick(object sender, RoutedEventArgs e)
        {
            UpdatePenHighlighter(true);
        }

        private void OnButtonEditModeSelectClick(object sender, RoutedEventArgs e)
        {
            UpdateEditMode(InkCanvasEditingMode.Select);
        }

        private void OnButtonEditModeInkClick(object sender, RoutedEventArgs e)
        {
            UpdateEditMode(InkCanvasEditingMode.InkAndGesture);
        }

        private void OnButtonEditModeEraseClick(object sender, RoutedEventArgs e)
        {
            UpdateEditMode(InkCanvasEditingMode.EraseByStroke);
        }

        private void OnButtonPagePrevClick(object sender, RoutedEventArgs e)
        {
            PrevPage();
        }

        private void OnButtonPageNextClick(object sender, RoutedEventArgs e)
        {
            NextPage();
        }

        private void OnButtonOpenRecordToolClick(object sender, RoutedEventArgs e)
        {
            //发送Win键+G，打开录制工具
            var ctrlAndAlt = new List<VirtualKeyCode>()
            { VirtualKeyCode.LWIN, VirtualKeyCode.VK_G };
            InputSimulator inputSimulator = new InputSimulator();
            inputSimulator.Keyboard.ModifiedKeyStroke(ctrlAndAlt, VirtualKeyCode.MULTIPLY);
        }

        private void OnButtonClearClick(object sender, RoutedEventArgs e)
        {
            //清空画笔
            canvasInk.Strokes.Clear();
        }

        #region JSON文件操作
        string _appsettingFilePath = null;
        Models.AppSetting _appSetting = new Models.AppSetting();
        ObservableCollection<Models.LessonDescription> _lessons = new ObservableCollection<Models.LessonDescription>();
        void GetAppSettingFilePath()
        {
            var exe = System.Reflection.Assembly.GetExecutingAssembly().Location;
            var fi = new System.IO.FileInfo(exe);
            _appsettingFilePath = System.IO.Path.Combine(fi.DirectoryName, "appsettings.json");
        }
        /// <summary>
        /// 我们的课件位于一个预先配置的文件夹下
        /// 默认是我的文档下的Lessons里面
        /// 文件名为appsettings.json
        /// 这个文件和程序放在一起
        /// </summary>
        void LoadLessonBaseDir()
        {
            //
            try
            {
                var doc = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                var defaultDir = System.IO.Path.Combine(doc, "Lessons");
                _appSetting.LessonBaseDir = defaultDir;
                if (!String.IsNullOrEmpty(_appsettingFilePath))
                {
                    if (System.IO.File.Exists(_appsettingFilePath))
                    {
                        //存在文件,读取
                        var json = System.IO.File.ReadAllText(_appsettingFilePath);
                        var setting = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.AppSetting>(json);
                        if(setting != null)
                        {
                            _appSetting.LessonBaseDir = setting.LessonBaseDir;
                        }

                        if(string.IsNullOrEmpty(_appSetting.LessonBaseDir))
                        {
                            _appSetting.LessonBaseDir = defaultDir;
                        }
                    }
                }

                if (!System.IO.Directory.Exists(_appSetting.LessonBaseDir))
                {
                    System.IO.Directory.CreateDirectory(_appSetting.LessonBaseDir);
                }
            }
            catch (Exception ex)
            {

            }
        }
        void SaveLessonBaseDir()
        {
            try
            {
                if (!String.IsNullOrEmpty(_appsettingFilePath))
                {
                    var json = Newtonsoft.Json.JsonConvert.SerializeObject(_appSetting);
                    System.IO.File.WriteAllText(_appsettingFilePath, json);
                }
            }
            catch (Exception exp)
            {
                //出错
            }
        }

        /// <summary>
        /// 列举BaseDir下的所有文件夹
        /// 文件夹的名称就是课件名称
        /// 文件夹下存在一个
        /// </summary>
        void LoadLessons(string baseDir)
        {
            listboxLessons.IsEnabled = false;
            _lessons.Clear();
            Task.Run(() => {
                try
                {
                    var dirs = System.IO.Directory.GetDirectories(baseDir);
                    foreach (var dir in dirs)
                    {
                        var d = new System.IO.DirectoryInfo(dir);
                        var jsonFile = System.IO.Path.Combine(d.FullName, "lesson.json");
                        var text = System.IO.File.ReadAllText(jsonFile);
                        var data = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.LessonDescription>(text);
                        this.Dispatcher.Invoke(new Action(() => {
                            _lessons.Add(data);
                        }));
                    }
                }
                catch(Exception exp)
                {
                    System.Diagnostics.Debug.WriteLine(exp);
                }
                finally
                {
                    this.Dispatcher.Invoke(new Action(() => {
                        listboxLessons.IsEnabled = true;
                    }));
                }
            });
        }
        #endregion
    }
}
